package cn.paraview.utils.collect;

import java.util.*;

/**
 * @author liushengbin
 * @version 1.0
 * @description zhichi 支持多key的Map，可以用于树形结构的数据
 * @email liushengbin7@gmail.com
 * @date 2018/10/31 5:48 PM
 */
public class MultiKeyMap<K, V> {

    private Map<K, Entry<K, V>> map = new HashMap<K, Entry<K, V>>();

    public V put(K pkey, K fkey, V value) {
        MultiKeyMap.Entry<K, V> entry = new MultiKeyMap.Entry<K, V>(fkey, value);
        map.put(pkey, entry);
        return value;
    }

    public V get(K pkey) {
        MultiKeyMap.Entry<K, V> entry = map.get(pkey);
        if (entry != null && !entry.isEmpty()) {
            return entry.getValue();
        } else {
            return null;
        }

    }

    public V remove(K pkey) {
        Entry<K, V> e = map.remove(pkey);
        return (e == null ? null : e.value);
    }

    public void clear() {
        map.clear();
    }

    public Collection<V> values() {
        Collection<V> result = null;
        if (!map.isEmpty()) {
            result = new ArrayList<V>(map.size());
            for (MultiKeyMap.Entry<K, V> entry : map.values()) {
                result.add(entry.getValue());
            }
        }
        return result;
    }

    public Collection<V> getByFKey(K fkey) {
        Collection<Entry<K, V>> entrys = map.values();
        Collection<V> result = null;
        if (!entrys.isEmpty()) {
            result = new ArrayList<V>();
            if (fkey == null) {
                return result;
            }

            for (MultiKeyMap.Entry<K, V> entry : entrys) {
                if (entry.getKey().equals(fkey)) {
                    result.add(entry.getValue());
                }

            }
        }
        return result;
    }

    static class Entry<K, V> {
        final K key;
        V value;

        Entry(K k, V v) {
            value = v;
            key = k;
        }

        public final K getKey() {
            return key;
        }

        public final V getValue() {
            return value;
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public boolean isEmpty() {
            return (this == null || getKey() == null);
        }

        public final boolean equals(MultiKeyMap.Entry<K, V> o) {
            if (!(o instanceof MultiKeyMap.Entry)) {
                return false;
            }

            Object k1 = getKey();
            Object k2 = o.getKey();
            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
                Object v1 = getValue();
                Object v2 = o.getValue();
                if (v1 == v2 || (v1 != null && v1.equals(v2))) {
                    return true;
                }

            }
            return false;
        }

        @Override
        public final int hashCode() {
            return (key == null ? 0 : key.hashCode()) ^
                    (value == null ? 0 : value.hashCode());
        }

        @Override
        public final String toString() {
            return getKey() + "=" + getValue();
        }
    }


    /**
     * Test
     *
     * @param args
     */
    public static void main(String[] args) {
        MultiKeyMap<Integer, String> map = new MultiKeyMap<Integer, String>();

        map.put(1, 0, "湖南");
        map.put(2, 1, "娄底");
        map.put(3, 1, "衡阳");
        map.put(4, 1, "长沙");
        map.put(5, 2, "新化");
        map.put(6, 2, "冷水江");


        List<String> list =  (List<String>) map.values();
        list.forEach(aa ->{
            System.out.println(aa);
        });

        List<String> ss = (List<String>) map.getByFKey(2);
        for (String s : ss) {
            System.out.println("下级："+s);
        }


    }
}



